Question: “How can I use vector data from Open Street Map?”

Objectives:

  • Explain how OpenStreetMap (OSM) geodata works
  • Demonstrate how to import, select, and visualise OSM vector data

library(dplyr)
library(sf)
library(ggplot2)
library(remotes)
remotes::install_github('ropensci/osmdata')
library(osmdata)
library(osmextract)

Import vector data from Open Street Map

What is Open Street Map?

Open Street Map (OSM) is a collaborative project which aims at mapping the world and sharing geospatial data in an open way. Anyone can contribute, by mapping geographical objects their encounter, by adding topical information on existing map objects (their name, function, capacity, etc.), or by mapping buildings and roads from satellite imagery (cf. HOT: Humanitarian OpenStreetMap Team).

This information is then validated by other users and eventually added to the common “map” or information system. This ensures that the information is accessible, open, verified, accurate and up-to-date.

The result looks like this: View of OSM web interface The geospatial data underlying this interface is made of geometrical objects (i.e. points, lines, polygons) and their associated tags (#building #height, #road #secondary #90kph, etc.).

How to extract geospatial data from Open Street Map?

Bonding-box

The first thing to do is to define the area within which you want to retrieve data, aka the bounding box. This can be defined easily using a place name and the function getbb() from the package osmdata.

“This function uses the free Nominatim API provided by OpenStreetMap to find the bounding box (bb) associated with place names.”

bb <- getbb('Delft', format_out = 'sf_polygon')

bb
Simple feature collection with 3 features and 0 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 4.320218 ymin: 9.474415 xmax: 79.73152 ymax: 52.0326
Geodetic CRS:  WGS 84
                        geometry
1 POLYGON ((4.320218 52.00807...
2 POLYGON ((4.320218 52.00807...
3 POLYGON ((79.65064 9.541313...
  • Why multiple polygons?

Because there are different responses from the API query, corresponding to different objects at the same location, or different objects are different locations.

Extracting features

A feature in the OSM language is a category or tag of a geospatial object. Features are described by general keys (e.g. “building”, “boundary”, “landuse”, “highway”), themselves decomposed into sub-categories (values) such as “farm”, “hotel” or “house” for buildings, “motorway”, “secondary” and “residential” for highway. This determines how they are represented on the map.

x <- opq(bbox = bb) %>% 
   add_osm_feature(key = 'building') %>%
    osmdata_sf ()

What is this x object made of? It is a table of all the buildings contained in the bounding box, which gives us their OSM id, their geometry and a range of attributes, such as their name, building material, building date, etc. The completion level of this table depends on user contributions and open resources (here for instance: BAG, different in other countries).

head(x$osm_polygons)
Simple feature collection with 6 features and 146 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 4.371179 ymin: 51.99641 xmax: 4.39319 ymax: 52.006
Geodetic CRS:  WGS 84
           osm_id             name access addr.city addr.country addr.housename
7536962   7536962 Sporthal Emerald   <NA>  Delfgauw           NL           <NA>
32017871 32017871             <NA>   <NA>      <NA>         <NA>           <NA>
32017872 32017872             <NA>   <NA>      <NA>         <NA>           <NA>
32017873 32017873             <NA>   <NA>      <NA>         <NA>           <NA>
32045333 32045333        Cambridge   <NA>      <NA>         <NA>           <NA>
32045334 32045334           Oxford   <NA>      <NA>         <NA>           <NA>
         addr.housenumber addr.postcode   addr.street alt_name amenity
7536962                 1        2645HH Florijnstraat     <NA>    <NA>
32017871             <NA>          <NA>          <NA>     <NA>    <NA>
32017872             <NA>          <NA>          <NA>     <NA>    <NA>
32017873             <NA>          <NA>          <NA>     <NA>    <NA>
32045333             <NA>          <NA>          <NA>     <NA>    <NA>
32045334             <NA>          <NA>          <NA>     <NA>    <NA>
         antenna.type area barrier bicycle_parking bridge bridge.support
7536962          <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32017871         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32017872         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32017873         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32045333         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
32045334         <NA> <NA>    <NA>            <NA>   <NA>           <NA>
           building building.colour building.flats building.level
7536962         yes            <NA>           <NA>           <NA>
32017871 apartments            <NA>           <NA>           <NA>
32017872 apartments            <NA>           <NA>           <NA>
32017873 apartments            <NA>           <NA>           <NA>
32045333        yes            <NA>           <NA>           <NA>
32045334 apartments            <NA>           <NA>           <NA>
         building.levels building.levels.aboveground
7536962             <NA>                        <NA>
32017871               6                        <NA>
32017872               6                        <NA>
32017873               6                        <NA>
32045333               5                        <NA>
32045334               5                        <NA>
         building.levels.underground building.material building.min_level
7536962                         <NA>              <NA>               <NA>
32017871                        <NA>             brick               <NA>
32017872                        <NA>             brick               <NA>
32017873                        <NA>             brick               <NA>
32045333                        <NA>              <NA>               <NA>
32045334                        <NA>              <NA>               <NA>
         building.part building.use capacity check_date check_date.existence
7536962           <NA>         <NA>     <NA>       <NA>                 <NA>
32017871          <NA>         <NA>     <NA>       <NA>                 <NA>
32017872          <NA>         <NA>     <NA>       <NA>                 <NA>
32017873          <NA>         <NA>     <NA>       <NA>                 <NA>
32045333          <NA>         <NA>     <NA>       <NA>                 <NA>
32045334          <NA>         <NA>     <NA>       <NA>                 <NA>
         club colour construction contact.phone content covered craft cuisine
7536962  <NA>   <NA>         <NA>          <NA>    <NA>    <NA>  <NA>    <NA>
32017871 <NA>   <NA>         <NA>          <NA>    <NA>    <NA>  <NA>    <NA>
32017872 <NA>   <NA>         <NA>          <NA>    <NA>    <NA>  <NA>    <NA>
32017873 <NA>   <NA>         <NA>          <NA>    <NA>    <NA>  <NA>    <NA>
32045333 <NA>   <NA>         <NA>          <NA>    <NA>    <NA>  <NA>    <NA>
32045334 <NA>   <NA>         <NA>          <NA>    <NA>    <NA>  <NA>    <NA>
         denomination description disused.amenity disused.building
7536962          <NA>        <NA>            <NA>             <NA>
32017871         <NA>        <NA>            <NA>             <NA>
32017872         <NA>        <NA>            <NA>             <NA>
32017873         <NA>        <NA>            <NA>             <NA>
32045333         <NA>        <NA>            <NA>             <NA>
32045334         <NA>        <NA>            <NA>             <NA>
         disused.building.colour disused.power disused.roof.colour
7536962                     <NA>          <NA>                <NA>
32017871                    <NA>          <NA>                <NA>
32017872                    <NA>          <NA>                <NA>
32017873                    <NA>          <NA>                <NA>
32045333                    <NA>          <NA>                <NA>
32045334                    <NA>          <NA>                <NA>
         drinking_water email emergency exit  fee fixme generator.method
7536962            <NA>  <NA>      <NA> <NA> <NA>  <NA>             <NA>
32017871           <NA>  <NA>      <NA> <NA> <NA>  <NA>             <NA>
32017872           <NA>  <NA>      <NA> <NA> <NA>  <NA>             <NA>
32017873           <NA>  <NA>      <NA> <NA> <NA>  <NA>             <NA>
32045333           <NA>  <NA>      <NA> <NA> <NA>  <NA>             <NA>
32045334           <NA>  <NA>      <NA> <NA> <NA>  <NA>             <NA>
         generator.output.electricity generator.source generator.type
7536962                          <NA>             <NA>           <NA>
32017871                         <NA>             <NA>           <NA>
32017872                         <NA>             <NA>           <NA>
32017873                         <NA>             <NA>           <NA>
32045333                         <NA>             <NA>           <NA>
32045334                         <NA>             <NA>           <NA>
         healthcare height heritage heritage.operator highway historic image
7536962        <NA>   <NA>     <NA>              <NA>    <NA>     <NA>  <NA>
32017871       <NA>   <NA>     <NA>              <NA>    <NA>     <NA>  <NA>
32017872       <NA>   <NA>     <NA>              <NA>    <NA>     <NA>  <NA>
32017873       <NA>   <NA>     <NA>              <NA>    <NA>     <NA>  <NA>
32045333       <NA>     15     <NA>              <NA>    <NA>     <NA>  <NA>
32045334       <NA>     15     <NA>              <NA>    <NA>     <NA>  <NA>
         layer       leisure level level.usage levels  lit loc_name location
7536962   <NA> sports_centre  <NA>        <NA>   <NA> <NA>     <NA>     <NA>
32017871  <NA>          <NA>  <NA>        <NA>   <NA> <NA>     <NA>     <NA>
32017872  <NA>          <NA>  <NA>        <NA>   <NA> <NA>     <NA>     <NA>
32017873  <NA>          <NA>  <NA>        <NA>   <NA> <NA>     <NA>     <NA>
32045333  <NA>          <NA>  <NA>        <NA>   <NA> <NA>     <NA>     <NA>
32045334  <NA>          <NA>  <NA>        <NA>   <NA> <NA>     <NA>     <NA>
         man_made material min.height min_height museum museum_type name.en
7536962      <NA>     <NA>       <NA>       <NA>   <NA>        <NA>    <NA>
32017871     <NA>     <NA>       <NA>       <NA>   <NA>        <NA>    <NA>
32017872     <NA>     <NA>       <NA>       <NA>   <NA>        <NA>    <NA>
32017873     <NA>     <NA>       <NA>       <NA>   <NA>        <NA>    <NA>
32045333     <NA>     <NA>       <NA>       <NA>   <NA>        <NA>    <NA>
32045334     <NA>     <NA>       <NA>       <NA>   <NA>        <NA>    <NA>
         name.nl name.ru name.zh network note old_name old_name.wikidata
7536962     <NA>    <NA>    <NA>    <NA> <NA>     <NA>              <NA>
32017871    <NA>    <NA>    <NA>    <NA> <NA>     <NA>              <NA>
32017872    <NA>    <NA>    <NA>    <NA> <NA>     <NA>              <NA>
32017873    <NA>    <NA>    <NA>    <NA> <NA>     <NA>              <NA>
32045333    <NA>    <NA>    <NA>    <NA> <NA>     <NA>              <NA>
32045334    <NA>    <NA>    <NA>    <NA> <NA>     <NA>              <NA>
         opening_hours opening_hours.signed operator operator.type
7536962           <NA>                 <NA>     <NA>          <NA>
32017871          <NA>                 <NA>     <NA>          <NA>
32017872          <NA>                 <NA>     <NA>          <NA>
32017873          <NA>                 <NA>     <NA>          <NA>
32045333          <NA>                 <NA>     <NA>          <NA>
32045334          <NA>                 <NA>     <NA>          <NA>
         operator.wikidata operator.wikipedia outdoor_seating parking
7536962               <NA>               <NA>            <NA>    <NA>
32017871              <NA>               <NA>            <NA>    <NA>
32017872              <NA>               <NA>            <NA>    <NA>
32017873              <NA>               <NA>            <NA>    <NA>
32045333              <NA>               <NA>            <NA>    <NA>
32045334              <NA>               <NA>            <NA>    <NA>
         payment.cash payment.maestro phone power private pumping_station  ref
7536962          <NA>            <NA>  <NA>  <NA>    <NA>            <NA> <NA>
32017871         <NA>            <NA>  <NA>  <NA>    <NA>            <NA> <NA>
32017872         <NA>            <NA>  <NA>  <NA>    <NA>            <NA> <NA>
32017873         <NA>            <NA>  <NA>  <NA>    <NA>            <NA> <NA>
32045333         <NA>            <NA>  <NA>  <NA>    <NA>            <NA> <NA>
32045334         <NA>            <NA>  <NA>  <NA>    <NA>            <NA> <NA>
                  ref.bag ref.bag.old ref.heritage ref.rce ref.tudelft religion
7536962  1926100000497049        <NA>         <NA>    <NA>        <NA>     <NA>
32017871  503100000024959        <NA>         <NA>    <NA>        <NA>     <NA>
32017872  503100000024957        <NA>         <NA>    <NA>        <NA>     <NA>
32017873  503100000024958        <NA>         <NA>    <NA>        <NA>     <NA>
32045333  503100000030621        <NA>         <NA>    <NA>        <NA>     <NA>
32045334  503100000030621        <NA>         <NA>    <NA>        <NA>     <NA>
         removed.building roof.colour roof.direction roof.edge roof.height
7536962              <NA>        <NA>           <NA>      <NA>        <NA>
32017871             <NA>        <NA>           <NA>      <NA>        <NA>
32017872             <NA>        <NA>           <NA>      <NA>        <NA>
32017873             <NA>        <NA>           <NA>      <NA>        <NA>
32045333             <NA>        <NA>           <NA>      <NA>        <NA>
32045334             <NA>        <NA>           <NA>      <NA>        <NA>
         roof.levels roof.material roof.orientation roof.ridge roof.shape
7536962         <NA>          <NA>             <NA>       <NA>       <NA>
32017871        <NA>          <NA>             <NA>       <NA>       flat
32017872        <NA>          <NA>             <NA>       <NA>       flat
32017873        <NA>          <NA>             <NA>       <NA>       flat
32045333        <NA>          <NA>             <NA>       <NA>       <NA>
32045334        <NA>          <NA>             <NA>       <NA>       <NA>
         service_times shop short_name smoking social_facility.for source
7536962           <NA> <NA>       <NA>    <NA>                <NA>    BAG
32017871          <NA> <NA>       <NA>    <NA>                <NA>    BAG
32017872          <NA> <NA>       <NA>    <NA>                <NA>    BAG
32017873          <NA> <NA>       <NA>    <NA>                <NA>    BAG
32045333          <NA> <NA>       <NA>    <NA>                <NA>    BAG
32045334          <NA> <NA>       <NA>    <NA>                <NA>    BAG
                   source.date source.name source.old_name sport start_date
7536962  2013-09-01;2013-11-26        <NA>            <NA>  <NA>       2001
32017871            2013-11-26        <NA>            <NA>  <NA>       2008
32017872            2013-11-26        <NA>            <NA>  <NA>       2008
32017873            2013-11-26        <NA>            <NA>  <NA>       2008
32045333            2013-11-26        <NA>            <NA>  <NA>       2007
32045334            2013-11-26        <NA>            <NA>  <NA>       2007
         street_cabinet substation surface survey.date toilets tourism
7536962            <NA>       <NA>    <NA>        <NA>    <NA>    <NA>
32017871           <NA>       <NA>    <NA>        <NA>    <NA>    <NA>
32017872           <NA>       <NA>    <NA>        <NA>    <NA>    <NA>
32017873           <NA>       <NA>    <NA>        <NA>    <NA>    <NA>
32045333           <NA>       <NA>    <NA>        <NA>    <NA>    <NA>
32045334           <NA>       <NA>    <NA>        <NA>    <NA>    <NA>
         tower.type type  url voltage watermill.disused website wheelchair
7536962        <NA> <NA> <NA>    <NA>              <NA>    <NA>       <NA>
32017871       <NA> <NA> <NA>    <NA>              <NA>    <NA>       <NA>
32017872       <NA> <NA> <NA>    <NA>              <NA>    <NA>       <NA>
32017873       <NA> <NA> <NA>    <NA>              <NA>    <NA>       <NA>
32045333       <NA> <NA> <NA>    <NA>              <NA>    <NA>       <NA>
32045334       <NA> <NA> <NA>    <NA>              <NA>    <NA>       <NA>
         wheelchair.description wikidata wikidata_1 wikipedia windmill.type
7536962                    <NA>     <NA>       <NA>      <NA>          <NA>
32017871                   <NA>     <NA>       <NA>      <NA>          <NA>
32017872                   <NA>     <NA>       <NA>      <NA>          <NA>
32017873                   <NA>     <NA>       <NA>      <NA>          <NA>
32045333                   <NA>     <NA>       <NA>      <NA>          <NA>
32045334                   <NA>     <NA>       <NA>      <NA>          <NA>
         windmill.vanes                       geometry
7536962            <NA> POLYGON ((4.392537 52.00466...
32017871           <NA> POLYGON ((4.37131 51.99711,...
32017872           <NA> POLYGON ((4.371664 51.9966,...
32017873           <NA> POLYGON ((4.371552 51.99676...
32045333           <NA> POLYGON ((4.372431 52.00586...
32045334           <NA> POLYGON ((4.372391 52.00555...

Mapping attributes

For instance: the building age focusing on post-war buildings.

Projections

First, we are going to select the polygons and reproject them with the Amersfoort/RD New projection, suited for maps centred on the Netherlands.

buildings <- x$osm_polygons %>% st_transform(.,crs=28992)

Mapping

Then we create a variable which a threshold at 1945. Every date prior to 1945 will be recoded 1945, so that buildings older than 1945 will be represented with the same shade.

Then we use the ggplot function to visualise the buildings by age. The specific function to represent information as a map is geom_sf(). The rest works like other graphs and visualisation, with aes() for the aesthetics.

buildings$build_date <- as.numeric(ifelse(buildings$start_date <1900, 1900,buildings$start_date))

 ggplot(data = buildings) +
   geom_sf(aes(fill = build_date, colour=build_date))  +
   scale_fill_viridis_c(option = "viridis")+
   scale_colour_viridis_c(option = "viridis")

So this reveals the historical centre of Delft and the various extensions, the first ring in the 1920s, towards the South-West of the city (1970s-1990s), East of the city (2000s) and North-West (2010s). This centre-periphery and sectoral urban development is quite common. Now for a less typical example, can you reproduce this map for the city of Rotterdam. But instead of pre-XXth century building, we want to look at pre-war buildings. It will take some time to extract all buildings, so we will check the result after the coffee break.

Challenge: Map building age in Rotterdam, with World War II as a threshold


Solution

Summary and keypoints

We have seen how OpenStreetMap (OSM) geodata works and how to import, select, and visualise OSM vector data. In short: - Use the osmextract package - Select features and attributes among osm tags - Use the ggplot package to map OSM data